const express = require('express')
const cors = require('cors')
const db = require('./db')
const flow = require('./tools/flow')
const integrationModules = require('./integrationModules')
const tool = require('./tools/tool')
const config = require('../config')
const multer = require('multer')
const bodyParser = require('body-parser')
const settings = require('./methods/settings')
const runner = require('./runner')
const path = require('path')
const fs = require('fs')
const http = require('http')

const app = express();
app.use(express.json())
app.use(cors())

async function connectDataBase() {
    await db.init({
        host: '47.115.209.43',
        // host: '127.0.0.1',
        user: 'root',
        password: 'Aiexaminer_123',
        // password: 'root',
        database: 'aiexaminer',
        port: 3306,
        charset: 'utf8mb4'
    })
}

module.exports = {
    async start(port = 0, handleStarted = () => { }) {
        // 连接数据库
        console.clear()
        console.log('正在连接数据库...')
        if (await flow(connectDataBase, (error) => {
            console.clear()
            console.log('无法连接数据库，原因：', error)
        })) {
            console.clear()
            // 成功连接数据库

            //数据库保活
            setInterval(() => {
                db.select(`select id from user`)
            }, 1000 * 60 * 60);

            // 解析接口模块
            let parsedPorts = await integrationModules()

            const user = tool.methods.user()
            for (let i = 0; i < parsedPorts.length; i++) {
                let c = parsedPorts[i]
                console.log(config.apiPrefix + c.api)
                app[(() => {
                    c.method = c.method.toLowerCase()
                    return c.method
                })()](config.apiPrefix + c.api, async (req, res) => {
                    let token = req.headers.token
                    if (c.auth) {
                        try {
                            await user.check(token, c.auth.admin === true)
                        } catch (error) {
                            res.send({
                                status: -1,
                                content: error.toString()
                            })
                            return
                        }
                    }
                    let data
                    try {
                        data = req.body
                    } catch (error) {
                        console.log(error)
                    }
                    try {
                        if (typeof (data) !== 'object') data = {}
                        data = {
                            currentUser: await (async () => {
                                try {
                                    return (await user.getSingleInfo.byId(JSON.parse(tool.decodeString(token)).id))
                                } catch (error) {
                                    return undefined
                                }
                            })(),
                            query: req.query,
                            param: data
                        }
                        if (c.noQueue) {
                            try {
                                let re = await c.func(data, req.headers, req)
                                res.send({
                                    status: 1,
                                    content: 'success',
                                    data: re
                                })
                            } catch (error) {
                                console.log(error)
                            }
                            return
                        }
                        // 到runner中执行
                        runner.add(c.func, res, req.headers, data, req)
                        return
                    } catch (error) {
                        res.send({
                            status: 0,
                            content: tool.string.delete.bySubString(error.toString(), 'Error:')
                        })
                        return
                    }
                })
            }
            // 完成接口模块解析

            // 文件相关接口
            const storage = multer.diskStorage({
                destination: 'files/',
                filename: function (req, file, cb) {
                    const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
                    const fileExtension = path.extname(file.originalname);
                    cb(null, file.fieldname + '-' + uniqueSuffix + fileExtension);
                }
            })
            const upload = multer({
                storage: storage, limits: {
                    fileSize: 50 * 1024 * 1024  // 50MB
                }
            })
            app.post(config.apiPrefix + '/file/upload', upload.single('file'), async (req, res) => {
                if (!req.file) {
                    res.status(400).json({ error: '上传失败' })
                } else {
                    res.json({
                        status: 1,
                        content: '上传成功',
                        data: req.file.filename
                    })
                }
            })
            app.get(config.apiPrefix + '/file/download/:filename', async (req, res) => {
                try {
                    let filename = req.params.filename;

                    // 简单限制非法字符，防止路径穿越攻击
                    if (filename.includes('..') || filename.includes('/') || filename.includes('\\')) {
                        return res.status(400).send('非法文件名');
                    }

                    // Base64 文件处理（数据库中的 blob 数据）
                    if (filename.includes('%b64%')) {
                        const sql = `SELECT data FROM file WHERE name = ?`;
                        const result = await execSQL(sql, [filename]);

                        if (!result || result.length === 0) {
                            return res.status(404).send('文件未找到');
                        }

                        const imageBuffer = result[0].data;

                        res.setHeader('Content-Type', 'image/jpeg');
                        res.setHeader('Cache-Control', 'public, max-age=31536000, immutable');
                        res.setHeader('Content-Length', imageBuffer.length); // 👈 必须添加
                        res.send(imageBuffer);
                        return;
                    }

                    // 文件系统中的文件处理
                    const filePath = path.join(__dirname, '../files', filename);

                    if (!fs.existsSync(filePath)) {
                        return res.status(404).json({
                            status: 0,
                            content: '无此文件'
                        });
                    }

                    res.setHeader('Content-Disposition', `attachment; filename="${filename}"`);
                    res.setHeader('Cache-Control', 'public, max-age=31536000, immutable');

                    const stat = fs.statSync(filePath);
                    res.setHeader('Content-Length', stat.size); // 👈 为了 OpenAI multimodal

                    const fileStream = fs.createReadStream(filePath);
                    fileStream.pipe(res);
                } catch (err) {
                    console.error('下载出错:', err);
                    res.status(500).send('服务器错误');
                }
            });
            app.use(bodyParser.json({ limit: '100mb' }))
            app.use(bodyParser.raw({ type: 'text/xml' }));
            app.use(bodyParser.urlencoded({ limit: '100mb', extended: true, parameterLimit: 1000000 }))
            // 完成文件相关接口

            // 初始化系统设置
            await settings.init()

            const server = http.createServer(app)

            server.listen(port, handleStarted)

            // 数据库保活
            setInterval(async () => {
                await tool.dbf().exe(`select * from user`, false)
            }, 1000 * 60)

            tool.methods.question().allQuestionString.get()
            setTimeout(() => {
                tool.methods.question().allQuestionString.get()
            }, 1000 * 60)
        }
    }
}